#这里选择0为正面，1为右面，2为后面，3为左面
from random import random;
from os import system;

def doit(intags,tag):
    tags=intags.copy();
    tags[tag]=tags[tag]+1;
    if((tag-1)>=0):
        tags[tag-1]=tags[tag-1]+1;
    try:
        tags[tag+1]=tags[tag+1]+1;
    except:
        pass;
    for i in range(len(tags)):
        tags[i]=tags[i]%4;
    return tags;

class Greedy:
    def __call__(self):
        try:
            self.printf('%s --> %s'%(str(self.tags),str(self.final)));
        except:
            raise ValueError("[Error][Greedy]No Values tags/final");
        self.main();
        self.printf(len(self.process));
        return self.process;
    
    def __init__(self,tags,final,magic,output):
        if(len(tags)!=len(final)):
            raise ValueError("[Error][Greedy]len(tags) should be equal to len(final)");
        self.tags=tags;
        self.final=final;
        self.process=[];#process每个元素是tag
        self.magic=magic;#在不同状况下采取不同值可以使算法简化
        self.output=output;
    
    def printf(self,msg,end='\n'):
        if(self.output==True):
            print(msg,end=end);
        
    def distance(self,tags):
        ret=0;
        for i in range(len(tags)):
            ret=ret+pow((tags[i]-tags[1]-final[i]),2)+self.magic;
        return int(ret);
    
    def main(self):
        while(1):
            if(self.final!=self.tags):
                tag=self._1time();
                try:
                    self.printf('%s -%d-> '%(str(self.tags),tag),end='')
                    self.tags=doit(self.tags,tag);
                    self.printf(self.tags);
                except:
                    raise RuntimeError("[Error][Global]doit");
                self.process.append(tag);
                if(len(self.process)>4):
                    if(self.process[-1]==self.process[-2] and self.process[-1]==self.process[-3] and self.process[-1]==self.process[-4]):
                        self.printf('%s -%d-> '%(str(self.tags),tag),end='');
                        self.tags=doit(self.tags,int(random()*len(self.tags)));
                        self.printf(self.tags);
            else:
                break;
    
    def _1time(self):
        return self._1time_sub(self.tags,self.final,range(len(self.tags)));

    def _1time_sub(self,tags,final,_range):
        distances=[];
        for i in _range:
            try:
                tmp=doit(tags,i);
            except:
                raise RuntimeError("[Error][Global]doit");
            try:
                distances.append(self.distance(tmp));
            except:
                raise RuntimeError("[Error][Greedy]distance");
        #懒得找序号排序函数，直接暴力，待优化
        #self.printf(distances);
        m=min(distances);
        minlist=[];
        #距离相同的就采用调整完后距离最小的且递归
        try:
            for j in range(len(distances)):
                if(distances[j]==m):
                   minlist.append(j);
        except:
            raise RuntimeError("[Error][Greedy][_1time]sort");
            
        if(len(minlist)==1):
            return minlist[0];
        else:
            try:
                return minlist[self._1time_sub(tags,final,minlist)];
            except:
                raise RuntimeError("[Error][Greedy][_1time]recursion");


tags=[2,1,0,3];
final=[0,0,0,0];
#算法不好暴力来凑
if(__name__=='__main__'):
    r=[];
    TIMES=10;
    for i in range(TIMES):
        t=[];
        for j in range(TIMES):
            print('magic=%d,%d/%d'%(i,j+1,TIMES));
            greedy=Greedy(tags,final,i,False);
            t.append(greedy());
        for j in t:
            if(r==[]):
                r=j;
            elif(len(r)>len(j)):
                r=j;
    print(r);
    system('pause>nul');